/************************* (C) COPYRIGHT 2008 Domain **************************
 * File Name   : sio.c                                                        *
 * Author      : Domain                                                       *
 * E-mail      : do.main@msn.com                                              *
 * Version     : 1.0                                                          *
 * Date        : 2008/6/26                                                    *
 * Description :                                                              *
 ******************************************************************************/

#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/sio.h"
#include "config.h"
#include "usart.h"
#include <string.h>

#if PPP_DEBUG
#include <stdio.h>
#include <stdarg.h>
#endif

typedef void* sio_fd_t;

/*static int sio_abort=0;*/

/* \\.\pipe\lwip0 */
/* pppd /dev/ttyS0 logfile mylog debug nocrtscts local noauth noccp ms-dns 212.27.54.252 192.168.0.4:192.168.0.5
 */

/**
 * SIO_DEBUG: Enable debugging for SIO.
 */
#ifndef SIO_DEBUG
#define SIO_DEBUG    LWIP_DBG_OFF
#endif


/**
* Open serial port entry point from serial protocol (slipif, pppif)
* @param devnum the device number to use, i.e. ttySx, comx:, etc. there x = devnum
* @return psio struct, contains sio instance data, use when calling sio functions
*/
sio_fd_t sio_open(u8_t devnum)
{ 
  LWIP_DEBUGF( SIO_DEBUG, ("sio_open(%lu)\r\n", (u16)devnum));
  switch (devnum)
  {
    case  1: USART_Cmd(USART1, ENABLE);      return USART1;
	//case  2: USART_Cmd(USART2, ENABLE);      return USART2;
	case  3: USART_Cmd(USART3, ENABLE);      return USART3;
	default: USART_Cmd(USART_MODEM, ENABLE); return USART_MODEM;
  }
}

/**
 * Write a char to output data stream
 * @param num char to write to output stream
 * @param psio struct, contains sio instance data, given by sio_open
 */
void sio_send(u8_t num, sio_fd_t psio)
{ 
  LWIP_DEBUGF( SIO_DEBUG, ("sio_send(%lu)\r\n", (u16)num));
  while (!PutByte((USART_TypeDef*)psio, num))
  {
  }
  return;
}

/**
 * Read a char from incoming data stream, this call blocks until data has arrived
 * @param psio siostatus struct, contains sio instance data, given by sio_open
 * @return char read from input stream
 */
u8_t sio_recv(sio_fd_t psio)
{ 
  u8_t byte = 0;
  LWIP_DEBUGF( SIO_DEBUG, ("sio_recv()\r\n"));
  while (!GetByte((USART_TypeDef*)psio, &byte))
  {
  }
  LWIP_DEBUGF( SIO_DEBUG, ("sio_recv()=%lu\r\n", byte));
  return byte;
}

u32_t sio_read(sio_fd_t psio, u8_t * data, u32_t len)
{ 
  u32_t dwNbBytesReadden = 0;
  u8_t byte = 0;
  LWIP_DEBUGF( SIO_DEBUG, ("sio_read()...\r\n"));

  //dwNbBytesReadden = GetDataLength((USART_TypeDef*)psio);
  //if (dwNbBytesReadden < len)
    //len = dwNbBytesReadden;
  //dwNbBytesReadden = 0;
  /*while (dwNbBytesReadden < len)
  {
    while (!GetByte((USART_TypeDef*)psio, &byte))
	{
	}
	data[dwNbBytesReadden++] = byte;
  }*/
  while ((dwNbBytesReadden < len) && (GetByte((USART_TypeDef*)psio, &byte)))
    data[dwNbBytesReadden++] = byte;

  LWIP_DEBUGF( SIO_DEBUG, ("sio_read()=%lu bytes\r\n", dwNbBytesReadden));
  /*#ifdef DEBUG
  if (dwNbBytesReadden > 0)
    DebugData(DEBUG_LEVEL_DETAIL, data, dwNbBytesReadden, "sio_read = ");
  #endif*/
  return dwNbBytesReadden;
}

extern int Send2Channel(int port, const char *format, ...);

u32_t sio_write(sio_fd_t psio, u8_t * data, u32_t len)
{ 
  u32_t dwNbBytesWritten = 0;
  LWIP_DEBUGF( SIO_DEBUG, ("sio_write()...\r\n"));
  /*while (dwNbBytesWritten < len)
  {
	while (!PutByte((USART_TypeDef*)psio, data[dwNbBytesWritten]))
	{
	}
	dwNbBytesWritten++;
  }*/
  dwNbBytesWritten = len;
  //DebugData(DEBUG_LEVEL_DETAIL, data, len, "sio_write = ");
  Send2Channel(1, (const char*)data, len);
  LWIP_DEBUGF( SIO_DEBUG, ("sio_write()=%lu bytes\r\n", dwNbBytesWritten));
  //DebugData(DEBUG_LEVEL_DETAIL, data, dwNbBytesWritten, "sio_write = ");
  return dwNbBytesWritten;
}

void sio_read_abort(sio_fd_t psio)
{ 
  LWIP_UNUSED_ARG(psio);
  LWIP_DEBUGF( SIO_DEBUG, ("sio_read_abort() !!!!!...\r\n"));
  ClearBuffer(USART_MODEM);
  return;
}

#if PPP_DEBUG
/*void ppp_trace( int level, const char *format, ...)
{ int len;
  char buffer[1024];
  va_list argList;

  LWIP_UNUSED_ARG(level);

  va_start  ( argList, format);
  len=vsprintf( buffer, format, argList);
  buffer[len-1]='\0';
  va_end    ( argList);
  fprintf(F_DEBUG, "%s\r\n", buffer);
}*/

int nprintf( char *buffer, size_t count, const char *format, ...)
{ int len;
  va_list argList;

  LWIP_UNUSED_ARG(count);

  va_start  ( argList, format);
  len=vsprintf( buffer, format, argList);
  buffer[len-1]='\0';
  va_end    ( argList);
  return len;
}
#endif /* PPP_DEBUG */

/************************* (C) COPYRIGHT 2008 Domain ******* END OF FILE ******/
